using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.IO;

namespace WCell.Core.Addons
{
	/// <summary>
	/// A full description of a plugin to be loaded
	/// </summary>
	public class WCellAddonDescriptor
	{
		/// <summary>
		/// Path to the Assembly that contains the Addon
		/// </summary>
		public readonly string FilePath;

		/// <summary>
		/// Fully specified type-name of the Addon within the Assembly to be found in FilePath 
		/// (or null if the Assembly is only a simple library)
		/// </summary>
		public readonly string TypeName;


		public WCellAddonDescriptor(string filePath, string typeName)
		{
			FilePath = Path.GetFullPath(filePath);
			TypeName = typeName;
		}

		/// <summary>
		/// The Directory where the Addon has been found
		/// </summary>
		public string Directory
		{
			get { return Path.GetDirectoryName(FilePath);  }
		}

		/// <summary>
		/// Whether the Assembly exists at this Descriptor's FilePath
		/// </summary>
		public bool Exists
		{
			get
			{
				return File.Exists(FilePath);
			}
		}

		/// <summary>
		/// Parses the given string of descriptors (using the default format) and adds them to the given list.
		/// The default format:
		/// All descriptors are seperated by ";" and each consist of one or two parts, seperated by ","; the first part
		/// being the filename and the 2nd part (not necessarily needed) the fully qualified 
		/// typename of the Addon-class.
		/// </summary>
		/// <param name="dir">The dir to look in for the Addon-Assemblies.</param>
		/// <param name="descriptorString">eg.: MyDllFile, My.NameSpace.MyAddonClass; My2ndFileIsJustALib; AnotherAddonFile, SomeOther.AddonClass</param>
		public static void ParseDefault(string dir, string descriptorString)
		{
			dir = new DirectoryInfo(dir).FullName;
			foreach (var descStr in descriptorString.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries))
			{
				var descParts = descStr.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
				if (descParts.Length > 0)
				{
					var fileName = descParts[0].Trim();
					if (!Path.IsPathRooted(fileName))
					{
						fileName = Path.Combine(dir, fileName);
					}

					string typeName;
					if (descParts.Length > 1)
					{
						typeName = descParts[1].Trim();
					}
					else
					{
						typeName = null;
					}

					 var desc = new WCellAddonDescriptor(fileName, typeName);
					WCellAddonMgr.Descriptors.Add(desc);
				}
			}
		}

		public override string ToString()
		{
			return string.Format("\"{0}\"{1}", FilePath, TypeName != null ? (", Type: \"" + TypeName + "\"") : "");
		}
	}
}
